package qeug.shsh.helper;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
//import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.DispatchServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.parameter.SystemParamServiceHelper;
import okhttp3.*;
import org.springframework.util.Base64Utils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import qeug.shsh.facde.info.AuditDataV2;
import qeug.shsh.task.SupplierToMDMTaskPlugin;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class FacadeHelper {

    private static final Log log = LogFactory.getLog(SupplierToMDMTaskPlugin.class);

    /**
     * @param ip   ip地址
     * @param api  接口方法名
     * @param body 调用接口body参数
     */
    public static String postUrl(String ip, String api, String body) {
        String json = HttpRequest.post(ip + api)
                .header("", "")
                .body(body)
                .execute().body();
        return json;
    }

    /**
     * @param map 接口日志参数
     *            使用前查看方法
     *            方法内字段均为必录
     */
/*    public static String addApiLog(Map<String, Object> map) {
        ORM orm = ORM.create();
        DynamicObject apiLog = orm.newDynamicObject("qeug_jkrz");
        apiLog.set("username", map.get("operationModule"));//操作模块
        apiLog.set("opname", map.get("url"));//请求地址
        apiLog.set("opdesc", map.get("user"));//登录信息
        apiLog.set("qeug_request_mode", map.get("mode"));//请求方式
        apiLog.set("qeug_textfield1", map.get("action"));//操作方法
        apiLog.set("qeug_mainstring", map.get("mainstring"));//请求参数
        apiLog.set("qeug_responsebody", map.get("responsebody"));//返回参数
        apiLog.set("qeug_opdesc1", map.get("pdesc"));//操作状态
        apiLog.set("opdate", map.get("opdate"));//操作时间
        OperationResult qeug_jkrz = SaveServiceHelper.saveOperate("qeug_jkrz", new DynamicObject[]{apiLog});
        return qeug_jkrz.toString();
    }*/

    //接口日志
    public static void apiLog(Map<String, Object> map) {
        ORM orm = ORM.create();
        OperateOption option = OperateOption.create();
        DynamicObject apiLog = orm.newDynamicObject("qeug_interfacelog");
        apiLog.set("qeug_operation_module", map.get("operationModule"));//操作模块
        apiLog.set("qeug_addres", map.get("url"));//请求地址
        apiLog.set("qeug_ip", map.get("user"));//登录信息
        apiLog.set("qeug_request_method", map.get("mode"));//请求方式
        apiLog.set("qeug_operating_mode", map.get("action"));//操作方法
        apiLog.set("qeug_mainstring_tag", map.get("mainstring"));//请求参数
        apiLog.set("qeug_responsebody_tag", map.get("responsebody"));//返回参数
        apiLog.set("qeug_state", map.get("pdesc"));//操作状态
        apiLog.set("qeug_operation_times", map.get("opdate"));//操作时间
//        OperationResult qeug_interfaceLog = SaveServiceHelper.saveOperate("qeug_interfacelog", new DynamicObject[]{apiLog});

        OperationServiceHelper.executeOperate("save", "qeug_interfacelog", new DynamicObject[]{apiLog}, option);

//        qeug_interfaceLog.toString();
    }


    /**
     * @param map BPM审批回传
     *            审批记录日志参数
     *            使用前查看方法
     *            方法内字段均为必录
     */
    public static String addAduitLog(Map<String, Object> map, String isfull) {
        OperateOption option = OperateOption.create();
        DynamicObject auditLog = BusinessDataServiceHelper.
                loadSingle("qeug_auditlog", new QFilter("billno", "=", map.get("billno")).toArray());
        ORM orm = ORM.create();
        DynamicObject apiLog = orm.newDynamicObject("qeug_auditlog");
        if (auditLog != null) {
            apiLog = auditLog;
        }
        apiLog.set("billno", map.get("billno"));//单据编号
        apiLog.set("qeug_sourcesystem", "BPM");//单据编号
        apiLog.set("billstatus", "A");//单据状态
        //获取单据体集合
        DynamicObjectCollection collection = apiLog.getDynamicObjectCollection("entryentity");

        if ("1".equals(isfull)) {
            collection.clear();
        }
        //获取单据体的type
        DynamicObjectType type = collection.getDynamicObjectType();
        DynamicObject entry = new DynamicObject(type);
        entry.set("qeug_approvernum", map.get("approvernum"));//审批人工号
        entry.set("qeug_aprusermame", map.get("approvername"));//审批人姓名
        entry.set("qeug_stepwame", map.get("stepwame"));//审批岗位
        entry.set("qeug_appopinion", map.get("appopinion"));//审批意见
        entry.set("qeug_appresult", map.get("appresult"));//审批结果
        entry.set("qeug_apptime", map.get("apptime"));//审批时间
        entry.set("qeug_nextapruserld", map.get("nextapruserld"));//下一节点审批人工号
        entry.set("qeug_nextaprusername", map.get("nextaprusername"));//下一节点审批人姓名
        entry.set("qeug_islast", map.get("islast"));//是否最后节点
        entry.set("qeug_bpmid", map.get("bpmid"));//bpm唯一流程ID
        collection.add(entry);
        OperationServiceHelper.executeOperate("save", "qeug_auditlog", new DynamicObject[]{apiLog}, option);
        return null;
    }

    /**
     * @param map BPM结果回传接口(新)
     *            审批记录日志参数
     *            使用前查看方法
     */
    public static void addAduitLogV2(Map<String, Object> map, AuditDataV2 auditModel) {
        OperateOption option = OperateOption.create();
        DynamicObject auditLog = BusinessDataServiceHelper.
                loadSingle("qeug_auditlogv2", new QFilter("billno", "=", map.get("dataId")).toArray());
        ORM orm = ORM.create();
        DynamicObject apiLog = orm.newDynamicObject("qeug_auditlogv2");
        if (auditLog != null) {
            apiLog = auditLog;
        }
        apiLog.set("billno", map.get("dataId"));//单据编号
        apiLog.set("qeug_dataversion", map.get("dataVersion"));// 单据版本号
        apiLog.set("qeug_processname", map.get("processName"));// 流程名
        apiLog.set("qeug_incident", map.get("incident"));//实例号
        apiLog.set("qeug_bpm", map.get("bpm"));// 流程名+实例号
        apiLog.set("qeug_initiatorname", map.get("initiatorName"));//流程发起人
        apiLog.set("qeug_appresult", map.get("appResult"));//审批状态
        apiLog.set("qeug_currentusername", map.get("currentUserName"));//当前审批人

        // 获取单据体集合
        DynamicObjectCollection collection = apiLog.getDynamicObjectCollection("entryentity");
        List<AuditDataV2.appHistory> appHistory = auditModel.getAppHistory();
        for (int k = 0; k < appHistory.size(); k++) {
            AuditDataV2.appHistory appHistory1 = appHistory.get(k);
            DynamicObjectType type = collection.getDynamicObjectType();
            DynamicObject dynamicObject = new DynamicObject(type);
            // 设置字段值
            dynamicObject.set("qeug_loginname", appHistory1.getLoginName()); // 审批人编码
            dynamicObject.set("qeug_username", appHistory1.getUserName()); // 审批人姓名
            dynamicObject.set("qeug_stepname", appHistory1.getStepName()); // 审批节点
            dynamicObject.set("qeug_result", appHistory1.getResult()); // 审批结果
            dynamicObject.set("qeug_remark", appHistory1.getRemark()); // 审批意见
            dynamicObject.set("qeug_signtime", appHistory1.getSignTime()); // 审批时间
            // 将 DynamicObject 添加到集合中
            collection.add(dynamicObject);
        }
        OperationServiceHelper.executeOperate("save", "qeug_auditlogv2", new DynamicObject[]{apiLog}, option);
    }

    /**
     * @param map 付款结果回传日志参数
     *            使用前查看方法
     *            方法内字段均为必录
     */
    public static String logPayment(Map<String, Object> map) {
        OperateOption option = OperateOption.create();
        DynamicObject auditLog = BusinessDataServiceHelper.
                loadSingle("qeug_pushg6pay", new QFilter("billno", "=", map.get("billno")).toArray());
        ORM orm = ORM.create();
        DynamicObject apiLog = orm.newDynamicObject("qeug_pushg6pay");
        if (auditLog != null) {
            apiLog = auditLog;
        }
        apiLog.set("billno", map.get("billno"));//单据编号
        apiLog.set("billstatus", "A");//单据状态
        //获取单据体集合
        DynamicObjectCollection collection = apiLog.getDynamicObjectCollection("entryentity");
        //获取单据体的type
        DynamicObjectType type = collection.getDynamicObjectType();
        DynamicObject entry = new DynamicObject(type);
        entry.set("qeug_state", map.get("type"));//付款类型
        entry.set("qeug_paydates", map.get("date"));//付款日期
        entry.set("qeug_payamount", map.get("amount"));//付款金额

        collection.add(entry);
//        OperateOption saveOption = OperateOption.create();
//        saveOption.setVariableValue(OperateOptionConst.IGNOREWARN, String.valueOf(true));    // 不执行警告级别校验器
//        saveOption.setVariableValue(OperateOptionConst.IGNOREINTERACTION, String.valueOf(true));    // 不显示交互提示，自动执行到底
//        saveOption.setVariableValue(OperateOptionConst.STRICTVALIDATION, String.valueOf(true));        // 全部校验通过才保存
//        OperationResult qeug_pushg6pay = SaveServiceHelper.saveOperate("qeug_pushg6pay", new DynamicObject[]{apiLog}, saveOption);
        OperationServiceHelper.executeOperate("save", "qeug_pushg6pay", new DynamicObject[]{apiLog}, option);
        return null;
    }


    public static DynamicObject quereryData(String property, Object value, String entityName) {
        QFilter[] a = new QFilter[]{new QFilter(property, "=", value)};
        DynamicObject bos_dailyapplybil = BusinessDataServiceHelper.loadSingle(entityName, a);
        return bos_dailyapplybil;
    }

    /**
     * map转xml格式
     *
     * @param Map 主数据
     * @param all 外层标识
     * @param all 第二层标识
     * @return
     */
    public static String mapToXml(SortedMap<String, Object> Map, String all, String iner) {
        StringBuffer sb = new StringBuffer();
        if (all.equals("")) {
            sb.append("<" + iner + ">");
            Iterator iterator = Map.keySet().iterator();
            while (iterator.hasNext()) {
                Object key = iterator.next();
                Object value = Map.get(key);
                sb.append("<" + key + ">");
                sb.append(value);
                sb.append("</" + key + ">");
            }
        } else {
            sb.append("<" + all + ">");
            sb.append("<" + iner + ">");
            Iterator iterator = Map.keySet().iterator();
            while (iterator.hasNext()) {
                Object key = iterator.next();
                Object value = Map.get(key);
                sb.append("<" + key + ">");
                sb.append(value);
                sb.append("</" + key + ">");
            }
            sb.append("</" + iner + ">");
            sb.append("</" + all + ">");
        }
        return sb.toString();
    }

    //资金计划专用转换
    public static String mapToNestedXml(Map<String, Object> map, String rootTag) {
        StringBuilder sb = new StringBuilder();
        if ("cfb".equals(rootTag)) {
            sb.append("<data>");
        }
        sb.append("<").append(rootTag).append(">");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Map) {
                Map<String, Object> nestedMap = (Map<String, Object>) value;
                if (nestedMap.containsKey("GLang")) {
                    // 如果包含 GLang 键，则只保留 GLang 的值
                    sb.append("<").append(key).append(">").append(nestedMap.get("GLang")).append("</").append(key).append(">");
                } else {
                    // 否则递归处理
                    sb.append(mapToNestedXml(nestedMap, key));
                }
            } else if (value instanceof Collection) {
                for (Object item : (Collection<?>) value) {
                    if (item instanceof Map) {
                        sb.append(mapToNestedXml((Map<String, Object>) item, key));
                    }
                }
            } else {
                sb.append("<").append(key).append(">").append(value).append("</").append(key).append(">");
            }
        }
        sb.append("</").append(rootTag).append(">");
        if ("cfb".equals(rootTag)) {
            sb.append("</data>");
        }
        return sb.toString();
    }

    /**
     * @param toXml G6XML内部数据
     * @param bill  单据
     * @return 完善后的XML
     */

    //报销单完善xml
    public static String perfectXml(String toXml, DynamicObject bill) {
        String heart = "{ \"message\" : \"<![CDATA[ " +
                "<?xml version=\\\"1.0\\\"encoding=\\\"UTF-8\\\"?>" +
                "<fdlk>" +
                "    <code>18002</code>" +
                "    <batchNo>" + bill.get("billno") + DateUtil.format(new Date(), "yyyyMMddHHmmss") + "</batchNo>" +
                "    <nodeId/>" +
                "    <ackCode/>" +
                "    <channelId/>" +
                "    <clientName>费控系统</clientName>" +
                "    <clientId>CCS</clientId>" +
                "    <txDateTime>" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + "</txDateTime>";
        String xml = heart + toXml + "</fdlk>]]>\"}";
        return xml;
    }

    //付款申请完善xml
    public static String paymentApplicationXml(String toXml, DynamicObject bill) {
        String heart = "{ \"message\" : \"<![CDATA[ " +
                "<?xml version=\\\"1.0\\\"encoding=\\\"UTF-8\\\"?>" +
                "<fdlk>" +
                "    <code>18002</code>" +
                "    <batchNo>" + bill.get("billno") + DateUtil.format(new Date(), "yyyyMMddHHmmss") + "</batchNo>" +
                "    <nodeId/>" +
                "    <ackCode/>" +
                "    <channelId/>" +
                "    <clientName>费控系统</clientName>" +
                "    <clientId>CCS</clientId>" +
                "    <txDateTime>" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + "</txDateTime>";
        String xml = heart + toXml + "</fdlk>]]>\"}";
        return xml;
    }

    //资金计划完善xml
    public static String payFundPlanXml(String toXml, DynamicObject bill) {
        String heart = "{ \"message\" : \"<![CDATA[ " +
                "<?xml version=\\\"1.0\\\"encoding=\\\"UTF-8\\\"?>" +
                "<fdlk>" +
                "    <code>19002</code>" +
                "    <batchNo>" + bill.get("billno") + "</batchNo>" +
                "    <nodeId/>" +
                "    <ackCode/>" +
                "    <channelId/>" +
                "    <clientName>费控系统</clientName>" +
                "    <clientId>CCS</clientId>" +
                "    <txDateTime>" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + "</txDateTime>";
        String xml = heart + toXml + "</fdlk>]]>\"}";
        return xml;
    }
/*    public static String perfectXml(String toXml, DynamicObject bill) {
        String heart = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<fdlk>\n" +
                "    <code>19002</code>\n" +
                "    <batchNo>" + bill.get("billno") + "</batchNo>\n" +
                "    <nodeId></nodeId>\n" +
                "    <channelId>ibs</channelId>\n" +
                "    <clientId></clientId>\n" +
                "    <clientName></clientName>\n" +
                "    <txDateTime>" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + "</txDateTime>\n" +
                "    <data>";
        String tail = "</data>\n" +
                "</fdlk>";
        return heart + toXml + tail;
    }*/


    public static DynamicObject getDynamicObject(String entityName, String property, String value) {


        QFilter[] qFilters = new QFilter[]{
                new QFilter(property, QCP.equals, value)
        };
        DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(entityName, "*", qFilters);
        return dynamicObject;
    }


    public static String xmlToJson(String xml, String heart) {
        try {

            ObjectMapper xmlMapper = new ObjectMapper();
            JsonNode node = xmlMapper.readTree(xml);

            // Convert XML to JSON
            ObjectMapper jsonMapper = new ObjectMapper();
            ObjectNode jsonNode = jsonMapper.createObjectNode();
            jsonNode.set(heart, node);

            // Print JSON
            String json = jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
            return json;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String xmlToJson(String xml) {
        String json = null;
        xml = xml.replace("{\"returnMessage\":\"<?xml version='1.0'?>\\n", "")
                .replaceAll("\\\\n\\\\t", "")
                .replace("}", "")
                .replaceAll("\\\\/", "/")
                .replaceAll("\\\\n", "")
                .replaceAll("\"", "");
        try {
//            ObjectMapper xmlMapper = new XmlMapper();
//            JsonNode node = xmlMapper.readTree(xml);
//            ObjectMapper jsonMapper = new ObjectMapper();
//            json = jsonMapper.writeValueAsString(node);

        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
        return json;
    }

    public static String xmlJson(String xml) {
        String json = null;
        log.info("替换过前的的xml：" + xml);
        if (xml.contains("<\\?xml[^>]*\\?>")) {
            log.info("xml包含：" + xml);
        } else {
            log.info("xml不包含：" + xml);
        }
        xml = xml.replaceAll("<\\?xml[^>]*\\?>", "");
        log.info("替换过后的xml" + xml);
        try {
//            ObjectMapper xmlMapper = new XmlMapper();
//            JsonNode node = xmlMapper.readTree(xml);
//            ObjectMapper jsonMapper = new ObjectMapper();
//            json = jsonMapper.writeValueAsString(node);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    public static Element praseXml(String xml) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            try {

                Document document = builder.parse(new java.io.ByteArrayInputStream(xml.getBytes()));
                Element documentElement = document.getDocumentElement();
                return documentElement;
            } catch (SAXException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } catch (ParserConfigurationException e) {
            throw new RuntimeException(e);
        }


    }

    public static String getToken() throws IOException {
        String loginIP = RequestContext.get().getLoginIP();
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, "{\n  \"appId\": \"BPM\",\n  \"appSecret\": \"UdCvB2Q4j8mSjKrRQ73KFw==\",\n  \"tenantid\": \"shenghongpec\",\n  \"accountId\": \"2158221105834229760\",\n  \"language\": \"zh_CN\"\n}");
        Request request = new Request.Builder()
                .url("http://10.10.102.30:30088/ierp/api/getAppToken.do")
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Basic Y2NzdXNlcjpjY3Myc2FwcG9kZXY=")
                .build();
        Response response = client.newCall(request).execute();
        JSONObject jsonObject = JSONObject.parseObject(response.body().string());
        String app_token = jsonObject.getJSONObject("data").getString("app_token");
        JSONObject bodyjson = new JSONObject();
        bodyjson.put("user", "ID-000004");
        bodyjson.put("apptoken", app_token);
        bodyjson.put("tenantid", "shenghongpec");
        bodyjson.put("accountId", "2158221105834229760");
        bodyjson.put("usertype", "WorkerNumber");
        RequestBody body1 = RequestBody.create(mediaType, bodyjson.toJSONString());
        Request request1 = new Request.Builder()
                .url("http://10.10.102.30:30088/ierp/api/login.do")
                .method("POST", body1)
                .addHeader("Content-Type", "application/json")
                .build();
        Response response1 = client.newCall(request1).execute();
        JSONObject jsonObject1 = JSONObject.parseObject(response1.body().string());
        return jsonObject1.getJSONObject("data").getString("access_token");
    }


    public static String getSAPAPI(String body, String url) {
//        String sap_url = System.getProperty("sap.url");

        String basicAuthUserName = System.getProperty("sap.user");
        String basicAuthPassword = System.getProperty("sap.password");
//        String basicAuthUserName = "ccsuser";
//        String basicAuthPassword = "ccs2sappodev";
        String basic = basicAuthUserName + ":" + basicAuthPassword;
        String encoding = Base64Utils.encodeToString(basic.getBytes(StandardCharsets.UTF_8));
        String send_standard = HttpRequest.post(url)
                .header("Authorization", "Basic " + encoding)
                .body(body)
                .execute().body();
        return send_standard;
    }


    public static JSONArray getVoucher(String sapapi) {
        JSONObject sapApi = JSONObject.parseObject(sapapi);
        JSONArray array = sapApi.getJSONArray("ET_ZFIT00150");
        // 根据BELNR+BUKRS+GJAHR+MONAT分组
        Map<String, List<JSONObject>> groupedItems = new HashMap<>();
        if (array != null) {
            for (int i = 0; i < array.size(); i++) {
                JSONObject item = array.getJSONObject(i);
                String key = item.getString("BELNR") + "_" +
                        item.getString("BUKRS") + "_" +
                        item.getString("GJAHR") + "_" +
                        item.getString("MONAT");

                groupedItems.computeIfAbsent(key, k -> new ArrayList<>()).add(item);
            }
        } else {
            return null;
        }

        // 合并分组数据到JSONObject
        JSONArray mergedVouchers = new JSONArray();
        for (Map.Entry<String, List<JSONObject>> entry : groupedItems.entrySet()) {
            List<JSONObject> itemsInGroup = entry.getValue();
            if (itemsInGroup.isEmpty()) {
                continue;
            }

            // 取第一个元素的头信息
            JSONObject firstItem = itemsInGroup.get(0);
            JSONObject voucher = new JSONObject();
            voucher.put("BELNR", firstItem.getString("BELNR"));
            voucher.put("BUKRS", firstItem.getString("BUKRS"));
            voucher.put("GJAHR", firstItem.getString("GJAHR"));
            voucher.put("MONAT", firstItem.getString("MONAT"));
            voucher.put("BLDAT", firstItem.getString("BLDAT"));
            voucher.put("BUDAT", firstItem.getString("BUDAT"));
            voucher.put("BLART", firstItem.getString("BLART"));
            voucher.put("KURSF", firstItem.getString("KURSF"));
            voucher.put("WAERS", firstItem.getString("WAERS"));
            voucher.put("STJAH", firstItem.getString("STJAH"));
            voucher.put("STBLG", firstItem.getString("STBLG"));
            voucher.put("AWKEY", firstItem.getString("AWKEY"));

            // 填充明细行
            JSONArray items = new JSONArray();
            for (JSONObject item : itemsInGroup) {
                JSONObject voucherItem = new JSONObject();
                voucherItem.put("DOCLN", item.getString("DOCLN"));
                voucherItem.put("SGTXT", item.getString("SGTXT"));
                voucherItem.put("RACCT", item.getString("RACCT"));
                voucherItem.put("MATNR", item.getString("MATNR"));
                voucherItem.put("DRCRK", item.getString("DRCRK"));
                voucherItem.put("AUFNR", item.getString("AUFNR"));
                voucherItem.put("WSL", item.getString("WSL"));
                items.add(voucherItem);
            }
            voucher.put("items", items);
            mergedVouchers.add(voucher);
            System.out.println();
        }
        return mergedVouchers;
    }

    public static String formatNumber(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }

        // 检查字符串是否以负号结尾且前面是数字
        if (input.endsWith("-")) {
            String numberPart = input.substring(0, input.length() - 1);
            // 验证剩余部分是否为纯数字（允许空字符串视为无效输入）
            return "-" + numberPart;
        }
        // 如果不是负数或格式无效，直接返回原字符串
        return input;
    }

    public static String getDownloadUrl2(String serialNo) {
        String contextUrl = System.getProperty("domain.contextUrl");
        String desiredUrl = "";
        List<String> objects = new ArrayList<>();
        objects.add(serialNo);//发票流水号
        Map<String, Object> result = DispatchServiceHelper.invokeBizService("imc", "rim", "FpzsService", "query", objects);
        Object errcode = result.get("errcode");//请求状态码，为0000表示成功
        if (errcode.equals("0000")) {
            String invoiceNo = "";
            Object data = result.get("data");//请求返回数据
            JSONArray jsonArray = JSONArray.parseArray(data.toString());
            for (int i1 = 0; i1 < jsonArray.size(); i1++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i1);
                invoiceNo = jsonObject.getString("downloadUrl");//下载地址
            }
            try {
                String downloadUrl = FacadeHelper.getDownloadUrl(contextUrl, invoiceNo, FacadeHelper.getToken());//调用下载地址转换
                int index = downloadUrl.indexOf('&');
                desiredUrl = (index != -1) ? downloadUrl.substring(0, index) : downloadUrl;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return desiredUrl;
    }

    public static String getDownloadUrl(String baseUrl, String filePath, String accessToken) throws UnsupportedEncodingException {
        // 下载文件地址使用download.do；预览文件地址使用preview.do
        String url = baseUrl + "/attachment/download.do?path=" + URLEncoder.encode(filePath, "utf-8") + "&access_token=" + accessToken;
        String value = accessToken + "~~" + System.currentTimeMillis();
        java.util.Base64.Encoder encoder = java.util.Base64.getEncoder();
        String encodeValue = encoder.encodeToString(value.getBytes("UTF-8"));
        String flag = "&";
        if (url != null && url.indexOf("?") == -1) {
            flag = "?";
        }
        return url + flag + "kdedcba=" + URLEncoder.encode(encodeValue, "UTF-8");
    }

    public static String getWBSInfo(String body) {
        String BODY = "";
        HashMap<String, Object> log = new HashMap<>();
        if (body == null) {
            JSONObject jsonbody = new JSONObject();
            BODY = jsonbody.toJSONString();
        } else {
            JSONObject jsonbody = new JSONObject();
            BODY = jsonbody.toJSONString();
        }
        String url = System.getProperty("sapwbs.url");
        url = "http://10.10.101.131:50000/RESTAdapter/CCS2S4_0001";
        String basicAuthUserName = "ccsuser";
        String basicAuthPassword = "ccs2sappodev";
        String basic = basicAuthUserName + ":" + basicAuthPassword;
        String encoding = Base64Utils.encodeToString(basic.getBytes(StandardCharsets.UTF_8));
        String wbsInfo = HttpRequest.post(url)
                .header("Authorization", "Basic " + encoding)
                .body(body)
                .execute().body();
//        String wbsInfo = FacadeHelper.getSAPAPI(BODY, url);
        JSONObject jsonObject = JSONObject.parseObject(wbsInfo);
        JSONArray itemsArray = jsonObject.getJSONArray("items");

        // 2. 按STUFE字段分组（自动处理空格并转换为整数）
        Map<Integer, List<JSONObject>> groupedItems = new TreeMap<>(); // TreeMap自动按key升序排序

        for (Object itemObj : itemsArray) {
            JSONObject item = (JSONObject) itemObj;
            String stufeStr = item.getString("STUFE");
            if (stufeStr == null) continue; // 跳过无STUFE字段的项

            try {
                int level = Integer.parseInt(stufeStr.trim());
                groupedItems.computeIfAbsent(level, k -> new ArrayList<>()).add(item);
            } catch (NumberFormatException e) {
                System.err.println("无效的STUFE值: " + stufeStr);
                // 可选择忽略或单独处理非数字层级
            }
        }

        // 3. 构建结果JSONArray
        JSONArray resultArray = new JSONArray();
        for (Map.Entry<Integer, List<JSONObject>> entry : groupedItems.entrySet()) {
            JSONObject levelGroup = new JSONObject();
            levelGroup.put("level", entry.getKey());
            levelGroup.put("items", entry.getValue());
            resultArray.add(levelGroup);
        }
        String message = null;
        boolean err = true;
        for (int i = 0; i < resultArray.size(); i++) {
            DynamicObjectCollection dynamicObjects = new DynamicObjectCollection();
            JSONObject wbsInfos = resultArray.getJSONObject(i);
            JSONArray iteam = wbsInfos.getJSONArray("items");
            for (int j = 0; j < iteam.size(); j++) {
                JSONObject wbsinfo = iteam.getJSONObject(j);
                String POSID = wbsinfo.getString("POSID");//WBS编码
                String PSPNR = wbsinfo.getString("PSPNR");//wbs要素
                String PBUKR = wbsinfo.getString("PBUKR");//公司(业务实体)编码
                String PSPHI = wbsinfo.getString("PSPHI");//当前项目号
                String OBJNR = wbsinfo.getString("OBJNR");//对象号
                String STUFE = wbsinfo.getString("STUFE");//级别
                String UP = wbsinfo.getString("UP");//上级
                String DOWN = wbsinfo.getString("DOWN");//下级
                String POST1 = wbsinfo.getString("POST1");//WBS名称
                DynamicObject assistantData = ORM.create().newDynamicObject("bos_assistantdata_detail");
                QFilter[] q1 = new QFilter[]{new QFilter("number", QCP.equals, POSID)};
                DynamicObject dynamic = BusinessDataServiceHelper.loadSingle("bos_assistantdata_detail", q1);
                if (dynamic != null) {
                    assistantData = dynamic;
                }
                assistantData.set("number", POSID);//编码

                if (POST1 != null) {
                    assistantData.set("name", POST1);//名称
                } else {
                    assistantData.set("name", POSID);//名称
                }
                DynamicObject org = FacadeHelper.getDynamicObject("bos_org", "number", PBUKR);
                assistantData.set("qeug_company", org);//公司
                DynamicObject createorg = FacadeHelper.getDynamicObject("bos_org", "number", "5100");
                assistantData.set("createorg", createorg);//创建组织
                DynamicObject assistantdatagroup = FacadeHelper.getDynamicObject("bos_assistantdatagroup", "number", "01");
                assistantData.set("group", assistantdatagroup);//类别
                DynamicObject viewschema = FacadeHelper.getDynamicObject("bos_org_viewschema", "number", "16");
                assistantData.set("ctrlview", viewschema);//控制视图
                assistantData.set("ctrlstrategy", "6");//控制策略
                DynamicObject parent = FacadeHelper.getDynamicObject("bos_assistantdata_detail", "qeug_wbsfactor", UP);
                assistantData.set("parent", parent);//上级辅助资料
                assistantData.set("level", STUFE);//级次
                assistantData.set("qeug_wbsfactor", PSPNR);//WBS要素
                assistantData.set("status", "C");//数据状态
                assistantData.set("enable", "1");//可用
                dynamicObjects.add(assistantData);
            }
            OperationResult result = OperationServiceHelper.executeOperate("save", "bos_assistantdata_detail", dynamicObjects.toArray(new DynamicObject[]{}), null);
            String s = result.getValidateResult().getMessage();
            if (s.equals("")) {

            } else {
                err = false;
                message = message + s;
            }
            System.out.println();
        }
//        OperationResult result = SaveServiceHelper.saveOperate("bos_assistantdata_detail", dynamicObjects.toArray(new DynamicObject[]{}), null);
//        String basicAuthUserName = "ccsuser";
        log.put("operationModule", "获取wbs");
        log.put("url", url);
        log.put("user", basicAuthUserName);
        log.put("mode", "POST");
        log.put("action", "");
        log.put("opdate", new Date());
        log.put("mainstring", message);
        log.put("responsebody", wbsInfo);
        log.put("operating_mode", message);
        if (err) {
            log.put("pdesc", "成功");
        } else {
            log.put("pdesc", "失败");
        }
        FacadeHelper.apiLog(log);
        return "";
    }
}
